package logica_de_datos;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashSet;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

import comun.Capitulo;
import comun.CapituloVistaNoSi;
import comun.Imagen;
import comun.Pelicula;
import comun.PeliculaVistaNoSi;
import comun.Serie;
import comun.SigueSerie;
import comun.Usuario;
import comun.ValoracionCapitulo;
import comun.ValoracionPelicula;

public class GestorBD {

	private static GestorBD instance = null;

	private Connection conn;

	/**
	 * Obtener la instnacia del gestor de la base de datos.
	 * 
	 * @return GestorBD-> el gestor de la base de datos
	 */
	public static GestorBD getInstance() {
		if (instance == null)
			instance = new GestorBD();
		return instance;
	}

	/**
	 * 
	 * @throws ClassNotFoundException
	 * @throws SQLException
	 */
	public void connect() throws ClassNotFoundException {
		Class.forName("org.sqlite.JDBC");

		try {
			conn = DriverManager
					.getConnection("jdbc:sqlite:files/base_de_datos.sqlite");
		} catch (SQLException e) {
		}
	}

	/**
	 * Desconectarse del archivo sqlite.De la base de datos.
	 */
	public void disconnect() {
		try {
			conn.close();
		} catch (SQLException e) {
		}
	}

	// TODO-Imagen
	/**
	 * Dada una URL nos da la combinacion en byte de la imagen jpg.
	 * 
	 * @param filePath
	 *            Direccion de la imagen.
	 * @return Array de byte de la image.
	 * @throws IOException
	 *             Excepcion que se produce cuando no es un archivo correcto.
	 */
	public byte[] readImageFromFile(String filePath) throws IOException {
		BufferedImage image = ImageIO.read(new File(filePath));
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ImageIO.write(image, "jpg", baos);
		return baos.toByteArray();
	}

	/**
	 * Insertar la imagen deseada en la base de datos dado como File.
	 * 
	 * @param fil
	 *            File que se desea anadir a la base de datos.
	 * @throws IOException
	 *             Se lanza cuando lo que se quiere introducir no es de formato
	 *             jpg
	 */
	public void addImage(File fil) throws IOException {

		byte[] data = readImageFromFile(fil.getPath());

		String insertString = "INSERT INTO Imagenes VALUES (null,?, ?)";

		try {
			PreparedStatement stat = conn.prepareStatement(insertString);
			stat.setString(1, fil.getName());
			stat.setBytes(2, data);
			stat.executeUpdate();
		} catch (SQLException e) {
		}
	}

	/**
	 * Nos devuelve el objeto imagen segun el id dado.
	 * 
	 * @param id
	 *            -> De la imagen que queremos.
	 * @return (Obj) Imagen deseada
	 */
	public Imagen getImagenFromId(int id) {

		Imagen img = new Imagen();
		String selectString = "SELECT * FROM Imagenes where id=?";

		try {
			PreparedStatement stat = conn.prepareStatement(selectString);
			stat.setInt(1, id);

			ResultSet resultSet = stat.executeQuery();

			if (resultSet != null) {
				img.setId(resultSet.getInt("id"));
				img.setNombre(resultSet.getString("nombre"));
				img.setImg(new ImageIcon(resultSet.getBytes("imagen")));
			}

		} catch (SQLException e) {
			// No se da La sentencia sql esta bien escrita.
		}
		return img;
	}

	/**
	 * Listar todas las imagen que estan almacenadas en la base de datos.
	 * 
	 * @return HashSet con todas las imagen como (obj)
	 */
	public HashSet<Imagen> listarImagenes() {

		final HashSet<Imagen> lis = new HashSet<Imagen>();
		try {
			String selectString = "select * from Imagenes";
			Statement stat = conn.createStatement();

			ResultSet resultSet = stat.executeQuery(selectString);
			while (resultSet.next()) {
				Imagen img = new Imagen(resultSet.getInt("id"),
						resultSet.getString("nombre"), new ImageIcon(
								resultSet.getBytes("imagen")));
				lis.add(img);
			}
		} catch (SQLException e) {
		}
		return lis;
	}

	public void deleteImagen(int id_i) {

		try {
			PreparedStatement stat = conn
					.prepareStatement("delete from Imagenes where id=?");
			stat.setInt(1, id_i);
			stat.executeUpdate();
		} catch (SQLException e) {
		}
	}

	// TODO- ValoracionCapitulo
	/**
	 * Anadir una Valoracion a un capitulo ya existente, por parte de un usuario
	 * registrado.
	 * 
	 * @param vc
	 *            -> ValoracionCapitulo que se desea anadir.
	 */
	public void addValoracionCapitulo(final ValoracionCapitulo vc) {

		try {
			PreparedStatement stat = conn
					.prepareStatement("insert into tablaValoracionCapitulo values (?, ?, ?, ?)");
			stat.setInt(1, vc.getId_u());
			stat.setInt(2, vc.getId_c());
			stat.setInt(3, vc.getPuntuacion());
			stat.setString(4, vc.getComentario());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Borra todas las valoraciones dado un id_u, un id de usuario.
	 * 
	 * @param id_u
	 *            id del usuario del que se quiere borrar todos las
	 *            valoraciones.
	 */
	public void deleteValoracionCapituloAllFromId_u(int id_u) {
		try {

			PreparedStatement stat = conn
					.prepareStatement("delete from tablaValoracionCapitulo where id_u = ?");
			stat.setInt(1, id_u);
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Borra todas las valoraciones dado un id_c, un id de un capitulo.
	 * 
	 * @param id_c
	 *            id del capitulo del que se quiere borrar todos las
	 *            valoraciones.
	 */
	public void deleteValoracionCapituloAllFromId_c(int id_c) {

		try {
			PreparedStatement stat = conn
					.prepareStatement("delete from tablaValoracionCapitulo where id_c = ?");
			stat.setInt(1, id_c);
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Modificar la valoracion pasada por paramentro de la base de datos.
	 * 
	 * @param vc
	 *            -> Valoracion que se desea modificar
	 * @throws SQLException
	 *             No se da la excepcion.
	 */
	public void modifyValoracionCapitulo(final ValoracionCapitulo vc) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("update tablaValoracionCapitulo set puntuacion=? , comentario=? where id_u = ? AND id_c= ?");
			stat.setInt(1, vc.getPuntuacion());
			stat.setString(2, vc.getComentario());
			stat.setInt(3, vc.getId_u());
			stat.setInt(4, vc.getId_c());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	public HashSet<ValoracionCapitulo> listarValoracionCapitulo() {

		final HashSet<ValoracionCapitulo> valoraciones = new HashSet<ValoracionCapitulo>();
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat
					.executeQuery("select * from tablaValoracionCapitulo");
			while (rs.next()) {
				final ValoracionCapitulo vc = new ValoracionCapitulo(
						rs.getInt("id_u"), rs.getInt("id_c"),
						rs.getInt("puntuacion"), rs.getString("comentario"));
				valoraciones.add(vc);
			}
		} catch (SQLException e) {
		}
		return valoraciones;
	}

	/**
	 * Obtener todas las valoracioneCapitulos (Obj) realizadas sobre un
	 * capitulos dado su id de capitulo.
	 * 
	 * @param id_c
	 *            ->Id del capitulo que se desea obtner las valoraciones.
	 * @return HashSet con todas las valoraciones realizas
	 */
	public HashSet<ValoracionCapitulo> getAllValoracionCapituloFromId_c(int id_c) {

		final HashSet<ValoracionCapitulo> id_cap = new HashSet<ValoracionCapitulo>();
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat
					.executeQuery("select * from tablaValoracionCapitulo");
			while (rs.next()) {
				final ValoracionCapitulo vc = new ValoracionCapitulo(
						rs.getInt("id_u"), rs.getInt("id_c"),
						rs.getInt("puntuacion"), rs.getString("comentario"));
				id_cap.add(vc);
			}
		} catch (SQLException e) {
			// NO se da sql correcto
		}

		return id_cap;

	}

	/**
	 * Obtener los id de los capitulos que ha valorado un usuario en concreto
	 * dado su id.
	 * 
	 * @param id_u
	 *            -> Id del usuario del que desea obtener sus valoraciones
	 * @return HashSet<Integer> conteniendo las id_c Id de los capitulos
	 *         valorados.
	 */
	public HashSet<Integer> getId_cValoracionCapituloFromId_u(int id_u) {

		final HashSet<Integer> listId_cap = new HashSet<Integer>();

		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat
					.executeQuery("select id_c from tablaValoracionCapitulo where id_u="
							+ id_u);
			while (rs.next()) {
				final Integer i = new Integer(rs.getInt("id_c"));
				listId_cap.add(i);
			}
		} catch (SQLException e) {
		}
		return listId_cap;
	}

	/**
	 * Obtener una valoracionCapitulo concreta dando el id del usuario que la
	 * realizo y el capitulo al que hace referencia.
	 * 
	 * @param id_u
	 *            ->Id del usuario que realizo la valoracion.
	 * @param id_c
	 *            ->Id del capitulo que realizo la valoracion.
	 * @return (Obj) ValoracionCapitulo deseado o null si no se encuentra.
	 */
	public ValoracionCapitulo getValoracionCapitulo(int id_u, int id_c) {

		ValoracionCapitulo vc = null;
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat
					.executeQuery("select * from tablaValoracionCapitulo");
			if (rs.next()) {
				vc = new ValoracionCapitulo(rs.getInt("id_u"),
						rs.getInt("id_c"), rs.getInt("puntuacion"),
						rs.getString("comentario"));

			}
		} catch (SQLException e) {

		}
		return vc;
	}

	// TODO-ValoracionPelicula-OK
	public void addValoracionPelicula(final ValoracionPelicula vp) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("insert into tablaValoracionPelicula values (?, ?, ?, ?)");
			stat.setInt(1, vp.getId_u());
			stat.setInt(2, vp.getId_p());
			stat.setInt(3, vp.getPuntuacion());
			stat.setString(4, vp.getComentario());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	public void deleteValoracionPelicula(final ValoracionPelicula vp) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("delete from tablaValoracionPelicula where id_u = ? AND id_p= ?");
			stat.setInt(1, vp.getId_u());
			stat.setInt(2, vp.getId_p());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	public void modifyValoracionPelicula(final ValoracionPelicula vp) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("update tablaValoracionPelicula set puntuacion=? , comentario=? where id_u = ? AND id_p= ?");
			stat.setInt(1, vp.getPuntuacion());
			stat.setString(2, vp.getComentario());
			stat.setInt(3, vp.getId_u());
			stat.setInt(4, vp.getId_p());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Obtener todas las valoraciones realizadas a las peliculas por parte de
	 * los usuario.
	 * 
	 * @return HashSet con <ValoracionPeliculas> que estan almacenas en la base
	 *         de datos.
	 */
	public HashSet<ValoracionPelicula> listarValoracionPelicula() {

		final HashSet<ValoracionPelicula> valoraciones = new HashSet<ValoracionPelicula>();
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat
					.executeQuery("select * from tablaValoracionPelicula");
			while (rs.next()) {
				final ValoracionPelicula vp = new ValoracionPelicula(
						rs.getInt("id_u"), rs.getInt("id_p"),
						rs.getInt("puntuacion"), rs.getString("comentario"));
				valoraciones.add(vp);
			}
		} catch (SQLException e) {
		}
		return valoraciones;
	}

	public HashSet<Integer> id_pValoracionPelicula(int id_u) {

		final HashSet<Integer> id_pelis = new HashSet<Integer>();
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat
					.executeQuery("select id_p from tablaValoracionPelicula");
			while (rs.next()) {
				final Integer id_p = rs.getInt("id_p");
				id_pelis.add(id_p);
			}
		} catch (SQLException e) {
		}
		return id_pelis;
	}

	/**
	 * Obtener todas las valoraciones realizadas sobre una pelicula que estan
	 * almacenadas en la base de datos.
	 * 
	 * @param id_p
	 *            -> id de la pelicula de la cual se desea obtener las
	 *            valoraciones.
	 * @return Un HashSet con todas las valoraciones(Obj) realizadas.
	 */
	public HashSet<ValoracionPelicula> ValoracionPeliculaDeId_p(int id_p) {

		final HashSet<ValoracionPelicula> id_pelis = new HashSet<ValoracionPelicula>();

		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat
					.executeQuery("select * from tablaValoracionPelicula where id_p="
							+ id_p);
			while (rs.next()) {
				final ValoracionPelicula vp = new ValoracionPelicula(
						rs.getInt("id_u"), rs.getInt("id_p"),
						rs.getInt("puntuacion"), rs.getString("comentario"));

				id_pelis.add(vp);
			}
		} catch (SQLException e) {
		}
		return id_pelis;
	}

	// TODO Pelicula -OK
	/**
	 * Metodo para introducir peliculas en la base de datos con id automatico.
	 * 
	 * @param p
	 *            Pelicula a introducir (Obj)
	 */
	public void addPelicula(final Pelicula p) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("insert into tablaPeliculas values (null,?, ?, ?, ?, ?, ?, ?)");
			stat.setString(1, p.getTitulo());
			stat.setString(2, p.getDirector());
			stat.setString(3, p.getPais());
			stat.setDouble(4, p.getDuracion());
			stat.setString(5, p.getActorPrincipal());
			stat.setInt(6, p.getOscar());
			stat.setDate(7, p.getFechaEstreno());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Pelicula borrar de la base de datos.
	 * 
	 * @param id_p
	 *            Id de la pelicula que queremos borrar.
	 */
	public void deletePelicula(final int id_p) {
		try {

			PreparedStatement stat = conn
					.prepareStatement("delete from tablaPeliculas where id = ?");
			stat.setInt(1, id_p);
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Modifica la pelicula de la base de datos, los datos deseados excepto el
	 * id.
	 * 
	 * @param p
	 *            Pelicula modificada, ha modificar.
	 */
	public void modifyPelicula(final Pelicula p) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("update tablaPeliculas set titulo=?, director=?, pais=?, duraccion=?, actorPrincipal=?, oscar=?, fechaEstreno=? where id=?");
			stat.setString(1, p.getTitulo());
			stat.setString(2, p.getDirector());
			stat.setString(3, p.getPais());
			stat.setDouble(4, p.getDuracion());
			stat.setString(5, p.getActorPrincipal());
			stat.setInt(6, p.getOscar());
			stat.setDate(7, p.getFechaEstreno());
			stat.setInt(8, p.getId_p());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Listar todos las peliculas de la base de datos
	 * 
	 * @return HashSet<Pelicula> Con todas las peliculas.
	 */
	public HashSet<Pelicula> listarPeliculas() {
		final HashSet<Pelicula> peliculas = new HashSet<Pelicula>();
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat.executeQuery("select * from tablaPeliculas");
			while (rs.next()) {
				final Pelicula peli = new Pelicula(rs.getInt("id"),
						rs.getString("titulo"), rs.getString("director"),
						rs.getString("pais"), rs.getInt("duraccion"),
						rs.getString("actorPrincipal"), rs.getInt("oscar"),
						rs.getDate("fechaEstreno"));
				peliculas.add(peli);
			}
			rs.close();
			stat.close();
		} catch (SQLException e) {
		}
		return peliculas;
	}

	/**
	 * Listar el id de las peliculas almacenadas.
	 * 
	 * @return HashSet<Integer> con el id de las peliculas.
	 */
	public HashSet<Integer> listarPeliculasSoloId() {

		final HashSet<Integer> PelId = new HashSet<Integer>();
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat.executeQuery("select id from tablaPeliculas");
			while (rs.next()) {
				final Integer integ = rs.getInt("id");
				PelId.add(integ);
			}
			rs.close();
			stat.close();
		} catch (SQLException e) {
		}
		return PelId;
	}

	/**
	 * Devuelve la pelicula deseada o un obj null.
	 * 
	 * @param id_p
	 *            id de la pelicula que se desea.
	 * @return Pelicula deseada o null.
	 */
	public Pelicula getPelicula(int id_p) {
		Pelicula p = null;
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat
					.executeQuery("select * from tablaPeliculas where id="
							+ id_p);

			while (rs.next()) {
				final Pelicula peli = new Pelicula(rs.getInt("id"),
						rs.getString("titulo"), rs.getString("director"),
						rs.getString("pais"), rs.getInt("duraccion"),
						rs.getString("actorPrincipal"), rs.getInt("oscar"),
						rs.getDate("fechaEstreno"));
				p = peli;
			}
			rs.close();
			stat.close();
		} catch (SQLException e) {
		}
		return p;
	}

	// TODO Serie-Ok
	/**
	 * Anadir serie a la base de datos.
	 * 
	 * @param s
	 *            Serie como (Obj) a introducir.
	 */
	public void addSerie(final Serie s) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("insert into tablaSeries values (null,?, ?, ?, ?, ?, ?)");
			stat.setString(1, s.getTitulo());
			stat.setString(2, s.getDirector());
			stat.setString(3, s.getPais());
			stat.setInt(4, s.getEMMY());
			stat.setDate(5, s.getFecha_ini());
			stat.setDate(6, s.getFecha_fin());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Borrar serie dada su id.
	 * 
	 * @param id_s
	 */
	public void deleteSerie(final int id_s) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("delete from tablaSeries where id = ?");
			stat.setInt(1, id_s);
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Modificar serie de la base de datos. Todo menos id de la serie.
	 * 
	 * @param s
	 *            Serie a modificar
	 */
	public void modifySerie(final Serie s) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("update tablaSeries set titulo=?, director=?, pais=?, EMMY=?, fechaIni=?, fechaFin=? where id=?");
			stat.setString(1, s.getTitulo());
			stat.setString(2, s.getDirector());
			stat.setString(3, s.getPais());
			stat.setInt(4, s.getEMMY());
			stat.setDate(5, s.getFecha_ini());
			stat.setDate(6, s.getFecha_fin());
			stat.setInt(7, s.getId_s());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Listar todas las series de base de datos.
	 * 
	 * @return HashSet con todas las series.
	 */
	public HashSet<Serie> listarSerie() {
		final HashSet<Serie> series = new HashSet<Serie>();
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat.executeQuery("select * from tablaSeries");
			while (rs.next()) {
				final Serie seri = new Serie(rs.getInt("id"),
						rs.getString("titulo"), rs.getString("director"),
						rs.getString("pais"), rs.getInt("EMMY"),
						rs.getDate("fechaIni"), rs.getDate("fechaFin"));
				series.add(seri);
			}
			rs.close();
			stat.close();
		} catch (SQLException e) {
		}
		return series;
	}

	/**
	 * Listar el id de todas la series.
	 * 
	 * @return Id de todas las series.
	 */
	public HashSet<Integer> listarSerieSoloId() {
		final HashSet<Integer> SerieId = new HashSet<Integer>();
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat.executeQuery("select id from tablaSeries");
			while (rs.next()) {
				final Integer integ = rs.getInt("id");
				SerieId.add(integ);
			}
			rs.close();
			stat.close();
		} catch (SQLException e) {
		}
		return SerieId;
	}

	/**
	 * Reset series de la base datos.
	 */
	public void resetSerie() {

		HashSet<Integer> SerieId = listarSerieSoloId();
		for (Integer id : SerieId) {
			deleteSerie(id);
		}
	}

	// TODO- Capitulo-OK

	public void addCapitulo(final Capitulo c) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("insert into tablaCapitulo values (null,?, ?, ?, ?, ?)");
			stat.setInt(1, c.getId_s());
			stat.setString(2, c.getNombre());
			stat.setInt(3, c.getNum_temp());
			stat.setInt(4, c.getNum_cap());
			stat.setDate(5, c.getFecha_emi());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	public void deleteCapitulo(final int id_c) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("delete from tablaCapitulo where id = ?");
			stat.setInt(1, id_c);
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	public void modifyCapitulo(final Capitulo c) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("update tablaCapitulo set id_s=?, nombre=?, numTemp=?, numCap=?, fechaEmi=? where id=?");
			stat.setInt(1, c.getId_s());
			stat.setString(2, c.getNombre());
			stat.setInt(3, c.getNum_temp());
			stat.setInt(4, c.getNum_cap());
			stat.setDate(5, c.getFecha_emi());
			stat.setInt(6, c.getId_c());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Listar todos los capitulos de la base de datos.
	 * 
	 * @return HashSet<Capitulo> con todos los capitulos.
	 */
	public HashSet<Capitulo> listarCapitulo() {
		final HashSet<Capitulo> capitulos = new HashSet<Capitulo>();
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat.executeQuery("select * from tablaCapitulo");
			while (rs.next()) {
				final Capitulo c = new Capitulo(rs.getInt("id"),
						rs.getInt("id_s"), rs.getString("nombre"),
						rs.getInt("numTemp"), rs.getInt("numCap"),
						rs.getDate("fechaEmi"));
				capitulos.add(c);
			}
			rs.close();
			stat.close();
		} catch (SQLException e) {
		}
		return capitulos;
	}

	/**
	 * Listar los id de los capitulos almacenados de la serie con id dado.
	 * 
	 * @param id_s
	 *            Id de la serie.
	 * @return HashSet<Capitulo> con todos los capitulos de la serie deseada.
	 */
	public HashSet<Capitulo> listarCapituloSoloId_s(int id_s) {

		final HashSet<Capitulo> capitulos = new HashSet<Capitulo>();
		try {
			String selectString = "select * from tablaCapitulo where id_s=";
			PreparedStatement stat = conn.prepareStatement(selectString);
			stat.setInt(1, id_s);
			ResultSet rs = stat.executeQuery();

			while (rs.next()) {

				final Capitulo c = new Capitulo(rs.getInt("id"),
						rs.getInt("id_s"), rs.getString("nombre"),
						rs.getInt("numTemp"), rs.getInt("numCap"),
						rs.getDate("fechaEmi"));
				capitulos.add(c);
			}
			rs.close();
			stat.close();
		} catch (SQLException e) {
		}
		return capitulos;

	}

	public HashSet<Integer> listarCapitulosSoloId() {
		final HashSet<Integer> CapId = new HashSet<Integer>();
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat.executeQuery("select id from tablaCapitulo");
			while (rs.next()) {
				final Integer integ = rs.getInt("id");
				CapId.add(integ);
			}
			rs.close();
			stat.close();
		} catch (SQLException e) {
		}
		return CapId;
	}

	// TODO-USUARIO-OK
	public void addUsuario(final Usuario usu) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("insert into tablaUsuarios values (null,?,?, ?,?)");
			stat.setInt(1, usu.getId_i());
			stat.setString(2, usu.getUsuario());
			stat.setString(3, usu.getPassWord());
			stat.setBoolean(4, usu.isEsAdmin());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	public void deleteUsuario(final int  id_u) {
		try{
		PreparedStatement stat = conn
				.prepareStatement("delete from tablaUsuarios where id = ?");
		stat.setInt(1, id_u);
		stat.executeUpdate();
		stat.close();
		}catch(SQLException e){}
	}

	public void modifyUsuario(final Usuario usu) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("update tablaUsuarios set id_i=?, usuario=?, passWord=?, isAdmin=? where id=?");

			stat.setInt(1, usu.getId_i());
			stat.setString(2, usu.getUsuario());
			stat.setString(3, usu.getPassWord());
			stat.setBoolean(4, usu.isEsAdmin());
			stat.setInt(5, usu.getId_u());
			stat.executeUpdate();

			stat.close();

		} catch (SQLException e) {
		}
	}

	public HashSet<Usuario> listarUsuario() {
		final HashSet<Usuario> usuarios = new HashSet<Usuario>();
		try{
		Statement stat = conn.createStatement();
		ResultSet rs = stat.executeQuery("select * from tablaUsuarios");

		while (rs.next()) {
			final Usuario usu = new Usuario();
			usu.setId_u(rs.getInt("id"));
			usu.setId_i(rs.getInt("id_i"));
			usu.setUsuario(rs.getString("usuario"));
			usu.setPassWord(rs.getString("passWord"));
			usu.setEsAdmin(rs.getBoolean("isAdmin"));
			usuarios.add(usu);
		}
		rs.close();
		stat.close();
		}catch(SQLException e){}
		return usuarios;
	}

	public HashSet<Integer> listarUsuarioSoloId() {
		final HashSet<Integer> usuariosId = new HashSet<Integer>();
		try{
		Statement stat = conn.createStatement();
		ResultSet rs = stat.executeQuery("select id from tablaUsuarios");
		while (rs.next()) {
			final Integer integ = rs.getInt("id");
			usuariosId.add(integ);
		}
		rs.close();
		stat.close();
		}catch(SQLException e){}
		return usuariosId;
	}

	// TODO PeliculaVistaNoSi-OK
	public void addPeliculaVistaNoSi(final PeliculaVistaNoSi pvns) {
		try{
		PreparedStatement stat = conn
				.prepareStatement("insert into tablaPeliculaVistaNoSi values(?,?,?)");
		stat.setInt(1, pvns.getId_u());
		stat.setInt(2, pvns.getId_p());
		stat.setBoolean(3, pvns.isVista());
		stat.executeUpdate();
		stat.close();
		}catch(SQLException e){}
	}

	public void deletePeliculaVistaNoSiFormId_u(int id_u) {
		try{
		PreparedStatement stat = conn
				.prepareStatement("delete from tablaPeliculaVistaNoSi where id_u = ?");
		stat.setInt(1, id_u);
		stat.executeUpdate();
		stat.close();
		}catch(SQLException e){}
	}

	public void deletePeliculaVistaNoSiFromId_p(int id_p)  {
		try{
		PreparedStatement stat = conn
				.prepareStatement("delete from tablaPeliculaVistaNoSi where id_p = ?");
		stat.setInt(1, id_p);
		stat.executeUpdate();
		stat.close();
		}catch(SQLException e){}
	}

	public void modifyPeliculaVistaNoSi(final PeliculaVistaNoSi pvns) {
		try{
		PreparedStatement stat = conn
				.prepareStatement("update tablaPeliculaVistaNoSi set vista=? where id_u = ? and id_p=?");
		stat.setBoolean(1, pvns.isVista());
		stat.setInt(2, pvns.getId_u());
		stat.setInt(3, pvns.getId_p());
		stat.executeUpdate();
		stat.close();
		}catch(SQLException e){}
	}

	public HashSet<PeliculaVistaNoSi> listarPeliculaVistaNoSi() {
		final HashSet<PeliculaVistaNoSi> peliculasVistasNoSi = new HashSet<PeliculaVistaNoSi>();
		try{
		Statement stat = conn.createStatement();
		ResultSet rs = stat
				.executeQuery("select * from tablaPeliculaVistaNoSi");
		while (rs.next()) {
			final PeliculaVistaNoSi pvns = new PeliculaVistaNoSi(
					rs.getInt("id_u"), rs.getInt("id_p"),
					rs.getBoolean("vista"));
			peliculasVistasNoSi.add(pvns);
		}
		rs.close();
		stat.close();
		}catch(SQLException e){}
		return peliculasVistasNoSi;
	}

	// TODO CapituloVistaNoSi-OK
	public void addCapituloVistaNoSi(final CapituloVistaNoSi cvns) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("insert into tablaCapituloVistaNoSi values(?,?,?)");
			stat.setInt(1, cvns.getId_u());
			stat.setInt(2, cvns.getId_c());
			stat.setBoolean(3, cvns.isVista());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	public void deleteCapituloVistaNoSi(final CapituloVistaNoSi cvns) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("delete from tablaCapituloVistaNoSi where id_u = ? and id_c=?");
			stat.setInt(1, cvns.getId_u());
			stat.setInt(2, cvns.getId_c());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	public void modifyCapituloVistaNoSi(final CapituloVistaNoSi cvns) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("update tablaCapituloVistaNoSi set vista=? where id_u = ? and id_c=?");
			stat.setBoolean(1, cvns.isVista());
			stat.setInt(2, cvns.getId_u());
			stat.setInt(3, cvns.getId_c());
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	public HashSet<CapituloVistaNoSi> listarCapituloVistaNoSi() {
		final HashSet<CapituloVistaNoSi> capitulosVistasNoSi = new HashSet<CapituloVistaNoSi>();
		try {
			Statement stat = conn.createStatement();
			ResultSet rs = stat
					.executeQuery("select * from tablaCapituloVistaNoSi");
			while (rs.next()) {
				final CapituloVistaNoSi cvns = new CapituloVistaNoSi(
						rs.getInt("id_u"), rs.getInt("id_c"),
						rs.getBoolean("vista"));
				capitulosVistasNoSi.add(cvns);
			}
			rs.close();
			stat.close();
		} catch (SQLException e) {
		}
		return capitulosVistasNoSi;
	}

	// TODO-SigueSerie-OK
	public void addSigueSerie(final SigueSerie sp) {
		try{
		PreparedStatement stat = conn
				.prepareStatement("insert into tablaSigueSerie values(?,?)");
		stat.setInt(1, sp.getId_u());
		stat.setInt(2, sp.getId_s());
		stat.executeUpdate();
		stat.close();
		}catch(SQLException e){}
	}

	/**
	 * Borrar de la base de datos la relacion entre un usuario concreto y una
	 * serie
	 * 
	 * @param id_u
	 *            -> Id del usuario que deja de seguir la serie.
	 * @param id_s
	 *            ->Id de la serie que se deja de seguir.
	 */
	public void deleteSigueSerie(int id_u, int id_s) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("delete from tablaSigueSerie where id_u = ? and id_s=?");
			stat.setInt(1, id_u);
			stat.setInt(2, id_s);
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Borrar todas las relaciones que existen entre un usuario y las series
	 * almacenadas.
	 * 
	 * @param id_u
	 *            -> Id del usuario del que no quiere que existan mas
	 *            relaciones.
	 */
	public void deleteSigueSerieAllFromId_u(int id_u) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("delete from tablaSigueSerie where id_u = ?");
			stat.setInt(1, id_u);
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	/**
	 * Borrar todas las relaciones que tenga una serie con los usuarios.
	 * 
	 * @param id_s
	 *            -> Id de la serie que se quiere que se deje de seguir.
	 */
	public void deleteSigueSerieAllFromId_s(int id_s) {
		try {
			PreparedStatement stat = conn
					.prepareStatement("delete from tablaSigueSerie where  id_s=?");
			stat.setInt(1, id_s);
			stat.executeUpdate();
			stat.close();
		} catch (SQLException e) {
		}
	}

	public HashSet<SigueSerie> listarSigueSerie() {
		final HashSet<SigueSerie> capitulosSeguidas = new HashSet<SigueSerie>();
		try{
		Statement stat = conn.createStatement();
		ResultSet rs = stat.executeQuery("select * from tablaSigueSerie");
		while (rs.next()) {
			final SigueSerie sc = new SigueSerie(rs.getInt("id_u"),
					rs.getInt("id_s"));
			capitulosSeguidas.add(sc);
		}
		rs.close();
		stat.close();
		}catch(SQLException e){}
		return capitulosSeguidas;
	}
}